﻿// @file  Utils.cs
// @author doublecat
// @date   2023-04-25
// @brief
// 
// Copyright (C) 2020  doublecat doublecat@163.com
// 
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// 
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
// 
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see http://www.gnu.org/licenses/.

#region 导入模块

using System.Collections;
using System.Text;

#endregion

namespace ModBus;

public static class Utils {
    /// <summary>
    /// 将字节数组转换成bit array
    /// </summary>
    /// <param name="data"></param>
    /// <param name="start"></param>
    /// <returns></returns>
    public static BitArray ToBitArray(this byte[] data, int start) {
        byte[] bytes = new byte[data.Length - start];
        Array.Copy(data, start, bytes, 0, bytes.Length);
        BitArray ba = new BitArray(bytes);
        return ba;
    }

    /// <summary>
    /// 将data字节数组从start开始的两个字节转换成ushort
    /// </summary>
    /// <param name="data"></param>
    /// <param name="start"></param>
    /// <returns></returns>
    public static ushort ToUShort(this byte[] data, int start) {
        ushort u16 = (ushort)((data[start] << 8) | data[start + 1]);
        return u16;
    }

    public static string ToHexString(this byte[] data) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < data.Length; i++) {
            sb.AppendFormat("0x{0:X2},", data[i]);
        }

        return sb.ToString().TrimEnd(',');
    }

    public static byte[] GetRange(this byte[] bytes, int start) {
        int    length = bytes.Length - start;
        byte[] result = new byte[length];
        Array.Copy(bytes, start, result, 0, length);
        return result;
    }

    public static ushort[] ToUShortArray(this byte[] bytes, int start = 0) {
        int length = bytes.Length - start;
        if (length % 2 != 0) {
            throw new ArgumentException("数组长度必须能整除2！");
        }

        ushort[] result = new ushort[length / 2];
        for (int i = 0; i < length / 2; i++) {
            int p0 = start + i * 2;
            int p1 = start + i * 2 + 1;
            result[i] = (ushort)((bytes[p0] << 8) | (bytes[p1]));
        }

        return result;
    }

    public static byte[] ToByteArray(this ushort[] data, int start = 0) {
        byte[] result = new byte[data.Length * 2];
        for (int i = 0; i < data.Length; i++) {
            int p0 = i * 2;
            int p1 = i * 2 + 1;
            result[p0] = (byte)(data[i] >> 8);
            result[p1] = (byte)(data[i] & 0xFF);
        }

        return result;
    }

    public static byte[] ToByteArray(this BitArray bits, int start = 0) {
        BitArray bitArray        = bits.LeftShift(start);
        int      bitsLength      = bits.Length - start;
        int      byteArrayLength = (bitsLength) / 8 + ((bitsLength % 8) > 0 ? 1 : 0);
        byte[]   rBytes          = new byte[byteArrayLength];

        for (int i = 0; i < byteArrayLength; i++) {
            for (int j = 0; j < 8; j++) {
                int index = i * 8 + j;
                if (index < bits.Length) {
                    rBytes[i] |= (byte)((bitArray[index] ? 1 : 0) << j);
                } else {
                    break;
                }
            }
        }

        return rBytes;
    }

    public static byte[] ToByteArray(this ushort u) {
        byte[] rBytes = new byte[2];
        rBytes[0] = (byte)(u >> 8);
        rBytes[1] = (byte)(u & 0xFF);
        return rBytes;
    }
}